/*
 *Copyright (c) [2019-2020]  C2comm, Inc.  All rights reserved.
 *
 *This program is free software; you can redistribute it and/or
 *modify it under the terms of the GNU General Public License
 *as published by the Free Software Foundation; either version 2
 *of the License, or (at your option) any later version.
 *
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program; If not, see <https://www.gnu.org/licenses/>
 */

/*
 *Vendor: C2comm
 *Version: 1.0
 *Filename: SMFlood.v
 *Target Device: Altera
 *Author : sunxiaotian@c2comm.cn
*/
module SMFlood(
input  wire         SYS2CORE_clk,
input  wire         SYS2CORE_rst_n,
input  wire         GA2SF_guard_pcf_valid,
input  wire [1:0]   GA2SF_guard_pcf,
output reg          SF2GA_guard_pcf_ready,
input  wire         GA2SF_guard_timeout,
output reg          SF2CS_cmd_valid,
output reg [7:0]    SF2CS_cmd_next_top_state,
output wire [7:0]   SF2CS_cmd_bottom_state,
input  wire [7:0]   current_top_state,
output reg          SF2CS_cmd_next_top_state_valid    
);

reg [7:0]  SMFlood_state;
reg flood_receive;
reg closed_window;

reg [1:0] local_timer_param;

parameter INIT_S=8'b0000_0001,
          MATCH_S=8'b0000_0010,
          COMPLETE_S=8'b0000_0100,
          C0_S=8'b0000_1000,
          C1_S=8'b0001_0000,
          C2_S=8'b0010_0000,
          C3_S=8'b0100_0000,
          C4_S=8'b1000_0000;
		  
assign SF2CS_cmd_bottom_state = SMFlood_state;    
     
always@(posedge SYS2CORE_clk or negedge SYS2CORE_rst_n )begin
	if(~SYS2CORE_rst_n)begin
		SF2CS_cmd_valid<=1'b0;
		SF2CS_cmd_next_top_state<=7'd0;
		flood_receive <= 1'b0;
		closed_window <= 1'b0;
		SF2GA_guard_pcf_ready<=1'b1;
		SF2CS_cmd_next_top_state_valid<=1'b0;
		SMFlood_state <= INIT_S;
		local_timer_param[1:0] <= 2'b00;
		
	end 
	else begin
		case(SMFlood_state)
			INIT_S:begin
				SF2CS_cmd_valid<=1'b0;
				SF2CS_cmd_next_top_state<=7'd0;
				SF2CS_cmd_next_top_state_valid<=1'b0;
				flood_receive <= 1'b0;
				closed_window <= 1'b0;
				SF2GA_guard_pcf_ready<=1'b1;
				if(current_top_state==8'b0000_1000)begin
					SMFlood_state<=MATCH_S;
				end 
				else begin
					SMFlood_state<=INIT_S;           
				end 
			end 
			MATCH_S:begin
				if(GA2SF_guard_pcf[1:0]==2'b00&&GA2SF_guard_pcf_valid==1'b1)begin//00:CS
					SF2GA_guard_pcf_ready<=1'b0;
					SMFlood_state<=C3_S;
				end 
				else if(GA2SF_guard_pcf[1:0]==2'b01&&GA2SF_guard_pcf_valid==1'b1&&flood_receive==1'b1&&closed_window==1'b0)begin  //01:CA
					 SF2GA_guard_pcf_ready<=1'b0;
					  SMFlood_state<=C4_S; 
				end 
				else if(GA2SF_guard_timeout==1'b1&&local_timer_param[1:0] == 2'b00)begin 
					 SF2GA_guard_pcf_ready<=1'b0;
					  SMFlood_state<=C0_S; 
				end 
				else if(GA2SF_guard_timeout==1'b1&&local_timer_param[1:0] == 2'b01)begin 
					 SF2GA_guard_pcf_ready<=1'b0;
					  SMFlood_state<=C1_S; 
				end 
				else if(GA2SF_guard_timeout==1'b1&&local_timer_param[1:0] == 2'b10)begin 
					 SF2GA_guard_pcf_ready<=1'b0;
					  SMFlood_state<=C2_S; 
				end 
				else begin
					SMFlood_state<=MATCH_S;
					SF2GA_guard_pcf_ready<=1'b1;
				end 
			end  
			C0_S:begin
				SF2CS_cmd_next_top_state_valid<=1'b1;
				SF2CS_cmd_next_top_state[7:0]<=8'b0000_1000; //SM_FLOOD
				//flood_receive <= 1'b1;
				local_timer_param[1:0] <= 2'b01;
				SF2GA_guard_pcf_ready<=1'b0;
				SMFlood_state<=COMPLETE_S;
			end 
			C1_S:begin
				SF2CS_cmd_next_top_state_valid<=1'b1;
				SF2CS_cmd_next_top_state[7:0]<=8'b0000_1000; //SM_FLOOD
				//closed_window <= 1'b1;
				flood_receive <= 1'b1;
				local_timer_param[1:0] <= 2'b10;
				SF2GA_guard_pcf_ready<=1'b0;
				SMFlood_state<=COMPLETE_S;
			end 
			C2_S:begin
				SF2CS_cmd_next_top_state_valid<=1'b1;
				SF2CS_cmd_next_top_state[7:0]<=8'b0000_0100;//SM_UNSYNC
				flood_receive <= 1'b0;
				closed_window <= 1'b0;
				local_timer_param[1:0] <= 2'b00;
				SF2GA_guard_pcf_ready<=1'b0;
				SMFlood_state<=COMPLETE_S;
			
			end 
			C3_S:begin
				SF2CS_cmd_next_top_state_valid<=1'b1;
				SF2CS_cmd_next_top_state[7:0]<=8'b0000_1000;//SM_FLOOD
				flood_receive <= 1'b0;
				closed_window <= 1'b0;
				local_timer_param[1:0] <= 2'b00;
				SF2GA_guard_pcf_ready<=1'b0;
				SMFlood_state<=COMPLETE_S;
			end 
			C4_S:begin
				SF2CS_cmd_next_top_state_valid<=1'b1;
				SF2CS_cmd_next_top_state[7:0]<=8'b0001_0000;//SM_WAIT_4_CYCLE_START_CS
				flood_receive <= 1'b0;
				closed_window <= 1'b0;
				local_timer_param[1:0] <= 2'b00;
				SF2GA_guard_pcf_ready<=1'b0;
				SMFlood_state<=COMPLETE_S;
			end 			
			COMPLETE_S:begin
				if(flood_receive==1'b1 || closed_window == 1'b1) begin
					SF2CS_cmd_next_top_state_valid<=1'b0;
					SMFlood_state<=MATCH_S; 
				end
				else begin
					SF2CS_cmd_next_top_state_valid<=1'b0;
					SMFlood_state<=INIT_S;   
				end
			end 
		endcase
	end     
end           
                   
endmodule